package com.pentofab.payrollmanagement.dao.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;

import com.pentofab.payrollmanagement.dao.model.Leave;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.utilities.Constants;
import com.pentofab.payrollmanagement.utilities.CustomTableConstants;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;

public class LeaveModuleUtility extends PayRollUtility {
	
	public static void validateLeaveObj(Leave leaveObject)
			throws BusinessException {
		debug("leaveObject : " + leaveObject);
		if (compareTwoDates(leaveObject.getFromDate(), leaveObject.getToDate()) > 0) {
			throw new BusinessException(TO_DATE_BEFORE_FROM_DATE);
		}
		if(leaveObject.getNoOfDays() > leaveObject.getAvaiblebleDays()){
			throw new BusinessException(INVALID_NUMBER_OF_DAYS);
		}

	}

	public static boolean isLeaveDeletable(String to_date) {

		try {
			
			Calendar todaysCal = Calendar.getInstance();
			
			SimpleDateFormat format = new SimpleDateFormat(Constants.dateFormat);
			Date inputDate = format.parse(to_date);
			
			Calendar leaveCalender = Calendar.getInstance();
			leaveCalender.setTime(inputDate);
			
			
			Date today = format.parse(format.format(new Date()));
			if(inputDate.compareTo(today) >= 0){
				return true;
			}else{
				
				if(todaysCal.get(Calendar.YEAR) == leaveCalender.get(Calendar.YEAR) && 
						todaysCal.get(Calendar.MONTH) == leaveCalender.get(Calendar.MONTH)){
					return true;
				}
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	
	public static void megeAttLevHoliData(ArrayList<HashMap<String, String>> attDetailList, HashMap<String, String> empInfoDataMap,
			 HashMap<String, HashMap<String, String>> attLeaveHolidayInfoMap,  HashMap<String , Integer> empWeekOffInfo,
			 ArrayList<String> holidayList,HashMap<String, String> totalWorkHours,
			 HashMap<String, String> hoursPerDayMap,  LinkedHashSet<String> daysOfMontSet) throws Exception{

		Iterator<HashMap<String, String>> attListIterator = attDetailList.listIterator();
		while(attListIterator.hasNext()){

			HashMap<String, String> current = attListIterator.next();
			String hoursPerDay = current.get(CustomTableConstants.hoursperday).trim();


			String curEmpId= current.get(CustomTableConstants.EMPI).toUpperCase();
			if(!hoursPerDay.equals("hrs")){
				hoursPerDayMap.put(curEmpId, hoursPerDay);
			}

			if(!empInfoDataMap.containsKey(curEmpId)){

				empInfoDataMap.put(curEmpId,curEmpId+", "+current.get(CustomTableConstants.name) +
						", "+current.get(CustomTableConstants.company)+
						", "+current.get(CustomTableConstants.department));
			}


			HashMap<String, String> existingAttInfoPerEmp = null;

			if(!attLeaveHolidayInfoMap.containsKey(curEmpId)){
				existingAttInfoPerEmp = new HashMap<String, String>();
				attLeaveHolidayInfoMap.put(curEmpId, existingAttInfoPerEmp);
			}

			existingAttInfoPerEmp =  attLeaveHolidayInfoMap.get(curEmpId);
			String attDate = current.get(CustomTableConstants.attDate);

			if(attDate.trim().equalsIgnoreCase("LEAVE")){

				String fromDate = current.get(CustomTableConstants.from_time);
				String toDate = current.get(CustomTableConstants.to_time);

				if(existingAttInfoPerEmp.get(fromDate) != null){

					existingAttInfoPerEmp.put(fromDate, existingAttInfoPerEmp.get(fromDate)+"(L)");

					if(!hoursPerDay.equals("")){

						computeTotalHrs(totalWorkHours,curEmpId, existingAttInfoPerEmp.get(toDate));
					}else{

						String presentData= totalWorkHours.get(curEmpId);
						if(presentData == null){
							totalWorkHours.put(curEmpId,"1");
						}else{
							totalWorkHours.put(curEmpId,String.valueOf(Integer.parseInt(presentData)+1));
						}
					}
				}else{

					existingAttInfoPerEmp.put(fromDate, "L");
				}


				if(!fromDate.equals(toDate)){
					if(existingAttInfoPerEmp.get(toDate) != null){

						existingAttInfoPerEmp.put(toDate, existingAttInfoPerEmp.get(toDate)+"(L)");

						if(!hoursPerDay.equals("")){
							computeTotalHrs(totalWorkHours,curEmpId, existingAttInfoPerEmp.get(toDate));
						}else{

							String presentData= totalWorkHours.get(curEmpId);
							if(presentData == null){
								totalWorkHours.put(curEmpId,"1");
							}else{
								totalWorkHours.put(curEmpId,String.valueOf(Integer.parseInt(presentData)+1));
							}
						}
					}else{

						existingAttInfoPerEmp.put(toDate, "(L)");
					}
				}

				SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
				Date date1 = sm.parse(fromDate);
				Date date2 = sm.parse(toDate);

				Calendar fromCal = Calendar.getInstance();
				Calendar toCal = Calendar.getInstance();
				fromCal.setTime(date1);
				toCal.setTime(date2);

				while(fromCal.getTime().before(toCal.getTime())){
					fromCal.add(Calendar.DATE, 1);
					if(fromCal.getTime().compareTo(toCal.getTime()) < 0)
						existingAttInfoPerEmp.put(sm.format(fromCal.getTime()), "L");
				}

			} else {
				Date attDateObj = PayRollUtility.convertStringToDate(attDate);
				SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
				attDate = sm.format(attDateObj);

				Calendar cal = Calendar.getInstance();
				cal.setTime(attDateObj);
				if (!current.get(CustomTableConstants.hoursperday).trim().equals("")) {

					System.out.println("hoursPerDay : "+hoursPerDay);


					int weekOfDay = cal.get(Calendar.DAY_OF_WEEK);

					String empWeekOff = current.get(CustomTableConstants.weeklyOff);

					int empWeekOffDay = -1;

					if (!empWeekOff.equals("")) {

						empWeekOffDay = PayRollUtility.dayOfWeek(empWeekOff);
						empWeekOffInfo.put(curEmpId, empWeekOffDay);
					}
					String total = "";
					if(weekOfDay == empWeekOffDay){

						total = current.get(CustomTableConstants.total);


						String currentTime = total;
						String[] time = currentTime.split(":");
						int hrs = Integer.parseInt(time[0]);
						int mins = Integer.parseInt(time[1]);

						String[] OutTime = hoursPerDay.split(":");
						int outHrs = Integer.parseInt(OutTime[0]);
						int outMins = Integer.parseInt(OutTime[1]);

						int totalHrs = hrs+outHrs;
						int totalMins = mins+outMins;

						if(totalMins > 60){
							totalHrs = totalHrs+1;
							totalMins = totalMins -60;
						}
						total = totalHrs+":"+totalMins;
						existingAttInfoPerEmp.put(attDate,total+"(WO)");
						computeTotalHrs(totalWorkHours,curEmpId, total);
					}else{

						total = current.get(CustomTableConstants.total);

						if(holidayList.contains(attDate)){

							total = current.get(CustomTableConstants.total);
							String currentTime = total;
							String[] time = currentTime.split(":");
							int hrs = Integer.parseInt(time[0]);
							int mins = Integer.parseInt(time[1]);

							String[] OutTime = hoursPerDay.split(":");
							int outHrs = Integer.parseInt(OutTime[0]);
							int outMins = Integer.parseInt(OutTime[1]);

							int totalHrs = hrs+outHrs;
							int totalMins = mins+outMins;

							if(totalMins > 60){
								totalHrs = totalHrs+1;
								totalMins = totalMins -60;
							}
							total = totalHrs+":"+totalMins;
							existingAttInfoPerEmp.put(attDate,total+"(H)");
							computeTotalHrs(totalWorkHours,curEmpId, total);
						}else{

							if(existingAttInfoPerEmp.get(attDate) == null){
								existingAttInfoPerEmp.put(attDate,total);
							}else{
								existingAttInfoPerEmp.put(attDate,total+existingAttInfoPerEmp.get(attDate));
							}
							computeTotalHrs(totalWorkHours,curEmpId, existingAttInfoPerEmp.get(attDate));
						}

					}

				} else {

					int weekOfDay = cal.get(Calendar.DAY_OF_WEEK);
					String empWeekOff = current.get(CustomTableConstants.weeklyOff);

					int empWeekOffDay = -1;
					if (!empWeekOff.equals("")) {

						empWeekOffDay = PayRollUtility.dayOfWeek(empWeekOff);
					}

					if(weekOfDay == empWeekOffDay){

						existingAttInfoPerEmp.put(attDate, "WO+P");
						empWeekOffInfo.put(curEmpId, empWeekOffDay);

						String presentData= totalWorkHours.get(curEmpId);

						if(presentData == null){
							totalWorkHours.put(curEmpId,"2");
						}else{
							totalWorkHours.put(curEmpId,String.valueOf(Integer.parseInt(presentData)+2));
						}


					}else if(holidayList.contains(attDate)){

						existingAttInfoPerEmp.put(attDate, "H1+P");

						String presentData= totalWorkHours.get(curEmpId);
						if(presentData == null){
							totalWorkHours.put(curEmpId,"2");
						}else{
							totalWorkHours.put(curEmpId,String.valueOf(Integer.parseInt(presentData)+2));
						}
					}
					else{
						existingAttInfoPerEmp.put(attDate, "P");

						String presentData= totalWorkHours.get(curEmpId);
						if(presentData == null){
							totalWorkHours.put(curEmpId,"1");
						}else{
							totalWorkHours.put(curEmpId,String.valueOf(Integer.parseInt(presentData)+1));
						}
					}


				}
			}
		}

		Iterator<String> empIdIterator  = empInfoDataMap.keySet().iterator();
		while (empIdIterator.hasNext()) {

			String empId = empIdIterator.next();
			String hoursPerDay = hoursPerDayMap.get(empId) != null ? hoursPerDayMap.get(empId) : "";
			Iterator<String> daySetIterator = daysOfMontSet.iterator();
			HashMap<String, String> attIndoMap = attLeaveHolidayInfoMap
					.get(empId);

			while (daySetIterator.hasNext()) {

				String date = daySetIterator.next();
				if (attIndoMap.get(date) == null) {
					if (holidayList.contains(date)) {
						if (!hoursPerDay.equals("")) {
							computeTotalHrs(totalWorkHours, empId, hoursPerDay);
						} else {

							String presentData = totalWorkHours.get(empId);
							if (presentData == null) {
								totalWorkHours.put(empId, "1");
							} else {
								totalWorkHours.put(empId,String.valueOf(Integer.parseInt(presentData) + 1));
							}
						}
					} else {

						if (empWeekOffInfo.get(empId) != null) {
							Calendar cal = Calendar.getInstance();
							int empWeekOff = empWeekOffInfo.get(empId);

							SimpleDateFormat sm = new SimpleDateFormat(
									"yyyy-MM-dd");
							sm.parse(date);
							Date attDate = sm.parse(date);
							cal.setTime(attDate);

							if (empWeekOff == cal.get(Calendar.DAY_OF_WEEK)) {

								if (!hoursPerDay.equals("")) {

									computeTotalHrs(totalWorkHours, empId,
											hoursPerDay);
								} else {

									String presentData = totalWorkHours
											.get(empId);
									if (presentData == null) {
										totalWorkHours.put(empId, "1");
									} else {
										totalWorkHours.put(empId,String.valueOf(Integer.parseInt(presentData) + 1));
									}
								}
							}
						}
					}
				}
			}
		}
	}

	public static void computeTotalHrs(HashMap<String, String> totalWorkHours,String empID, String hours){
		try{
		System.out.println("hours : "+hours);
		if(totalWorkHours.get(empID) == null){
			totalWorkHours.put(empID, hours);
		}else{
			String current = totalWorkHours.get(empID);
			
			
			String[] time = current.split(":");
			int hrs = Integer.parseInt(time[0]);
			int mins = Integer.parseInt(time[1]);
			
			String[] OutTime = hours.split(":");
			int outHrs = Integer.parseInt(OutTime[0]);
			int outMins = Integer.parseInt(OutTime[1]);
			
			int totalHrs = hrs+outHrs;
			int totalMins = mins+outMins;
			
			if(totalMins > 60){
				totalHrs = totalHrs+1;
				totalMins = totalMins -60;
			}
			
			totalWorkHours.put(empID, totalHrs+":"+totalMins);
		}
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
}
